package com.hzyl.famousreader.view.widget.core.animation;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;

/**
 * 水平翻页基类
 */
public abstract class HorizonAnimAbs extends AnimAbs {

  /**
   * 用户看到的Bitmap
   */
  protected Bitmap showBitmap;

  /**
   * 即将要隐藏的Bitmap
   */
  protected Bitmap noneBitmap;

  //可以使用 mLast代替
  private int mMoveX = 0;
  private int mMoveY = 0;
  //是否移动了
  private boolean isMove = false;
  //是否翻阅下一页。true表示翻到下一页，false表示上一页。
  private boolean isNext = false;

  //是否没下一页或者上一页
  private boolean noNext = false;
  //是否取消翻页
  protected boolean isCancel = false;

  public HorizonAnimAbs(View mView, int w, int h, OnPageChangeListener listener) {
    super(mView, w, h, listener);

    showBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.RGB_565);
    noneBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.RGB_565);
  }

  @Override
  public boolean onTouchEvent(MotionEvent event) {
    //获取点击位置
    int x = (int) event.getX();
    int y = (int) event.getY();
    //设置触摸点
    setTouchPoint(x, y);

    switch (event.getAction()) {
      case MotionEvent.ACTION_DOWN:
        //移动的点击位置
        mMoveX = 0;
        mMoveY = 0;
        //是否移动
        isMove = false;
        //是否存在下一章
        noNext = false;
        //是下一章还是前一章
        isNext = false;
        //是否正在执行动画
        isRunning = false;
        //取消
        isCancel = false;
        //设置起始位置的触摸点
        setStartPoint(x, y);
        //如果存在动画则取消动画
        abortAnim();
        break;
      case MotionEvent.ACTION_MOVE:
        final int slop = ViewConfiguration.get(mView.getContext()).getScaledTouchSlop();
        //判断是否移动了
        if (!isMove) {
          isMove = Math.abs(mStartX - x) > slop || Math.abs(mStartY - y) > slop;
        }

        if (isMove) {
          //判断是否是准备移动的状态(将要移动但是还没有移动)
          if (mMoveX == 0 && mMoveY == 0) {
            //判断翻得是上一页还是下一页
            if (x - mStartX > 0) {
              //上一页的参数配置
              isNext = false;
              boolean hasPrev = mListener.prev();
              setDirection(AnimDirectionEnum.PRE);
              //如果上一页不存在
              if (!hasPrev) {
                noNext = true;
                return true;
              }
            } else {
              //进行下一页的配置
              isNext = true;
              //判断是否下一页存在
              boolean hasNext = mListener.next();
              //设置动画方向
              setDirection(AnimDirectionEnum.NEXT);
              //如果不存在表示没有下一页了
              if (!hasNext) {
                noNext = true;
                return true;
              }
            }
          } else {
            //判断是否取消翻页
            if (isNext) {
              if (x - mMoveX > 0) {
                isCancel = true;
              } else {
                isCancel = false;
              }
            } else {
              if (x - mMoveX < 0) {
                isCancel = true;
              } else {
                isCancel = false;
              }
            }
          }

          mMoveX = x;
          mMoveY = y;
          isRunning = true;
          mView.invalidate();
        }
        break;
      case MotionEvent.ACTION_UP:
        if (!isMove) {
          if (x < mView.getWidth() / 2) {
            isNext = false;
          } else {
            isNext = true;
          }

          if (isNext) {
            //判断是否下一页存在
            boolean hasNext = mListener.next();
            //设置动画方向
            setDirection(AnimDirectionEnum.NEXT);
            if (!hasNext) {
              return true;
            }
          } else {
            boolean hasPrev = mListener.prev();
            setDirection(AnimDirectionEnum.PRE);
            if (!hasPrev) {
              return true;
            }
          }
        }

        // 是否取消翻页
        if (isCancel) {
          mListener.cancel();
        }

        // 开启翻页效果
        if (!noNext) {
          isRunning = true;
          startAnim();
          mView.invalidate();
        }
        break;
    }
    return true;
  }

  @Override
  public Bitmap getBgBitmap() {
    return showBitmap;
  }

  @Override
  public Bitmap getShowBitmap() {
    return showBitmap;
  }

  @Override
  public void scrollAnim() {
    if (mScroller.computeScrollOffset()) {
      int x = mScroller.getCurrX();
      int y = mScroller.getCurrY();

      setTouchPoint(x, y);

      if (mScroller.getFinalX() == x && mScroller.getFinalY() == y) {
        isRunning = false;
      }
      mView.postInvalidate();
    }
  }

  @Override
  protected void abortAnim() {
    if (!mScroller.isFinished()) {
      mScroller.abortAnimation();
      isRunning = false;
      setTouchPoint(mScroller.getFinalX(), mScroller.getFinalY());
      mView.postInvalidate();
    }
  }

  @Override
  public void draw(Canvas canvas) {
    if (isRunning) {
      drawAnim(canvas);
    } else {
      if (isCancel) {
        showBitmap = noneBitmap.copy(Bitmap.Config.RGB_565, true);
      }
      drawStatic(canvas);
    }
  }

  /**
   * 绘制动画
   */
  protected abstract void drawAnim(Canvas canvas);

  /**
   * 绘制静态页面
   */
  protected void drawStatic(Canvas canvas) {
    canvas.drawBitmap(showBitmap, 0, 0, null);
  }

  /**
   * 优化资源利用：切换到未被使用的Bitmap
   */
  public void switch2NoneBitmap() {
    Bitmap tmp = showBitmap;
    showBitmap = noneBitmap;
    noneBitmap = tmp;
  }

  public void resetBitmap(Bitmap bgBitmap, Bitmap showBitmap) {
    this.noneBitmap = bgBitmap;
    this.showBitmap = showBitmap;
  }
}
